package wiinf;

import de.avetana.javax.obex.ClientSession;
import de.avetana.javax.obex.HeaderSet;
import de.avetana.javax.obex.Operation;
import de.avetana.obexsolo.OBEXConnector;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author David Roos
 */
public class serverSender implements Runnable {
    public ClientSession cs;
    public HeaderSet hs;
    protected serverController server;
    protected HashMap hm;
    private Date date;
    private long tijd;
    private long huidig;
    private long opgeslagentijd;

    /**
     * Sender class om bestanden te versturen naar de cliënt
     *
     * @param server Instantie van de serverController die een nieuwe serverSender aanmaakt
     * @throws java.io.IOException
     */
    public serverSender(serverController server) throws IOException {
        this.server = server;
        hm = new HashMap();
    }

    /**
     * Haalt alle bluetooth adressen op uit een vector en plaatst deze in een Hashmap
     */
    public void vectorToHashMap() {
        for (int i = 0; i < server.getVector().size(); i++) {
            if (!hm.containsKey(server.getVector().elementAt(i).toString())) {
                hm.put(server.getVector().elementAt(i).toString(), 10);
            }
        }
    }

    /**
     * Maakt verbinding met de cliënts opgeslagen in de hashmap
     */
    public void maakVerbinding() {
        Set adressenset = hm.entrySet();
        Iterator adressen = adressenset.iterator();
        while (adressen.hasNext()) {
            Map.Entry entry = (Map.Entry) adressen.next();
            String next = entry.getKey().toString();
            String value = entry.getValue().toString();
            opgeslagentijd = Long.parseLong(value);
            Date currentTime = new Date();
            huidig = currentTime.getTime();

            if ((huidig - opgeslagentijd) < 600000) {
                continue;
            }

            String adrProto = "btgoep://" + next + ":9;authenticate=false;master=false;encrypt=false";
            try {
                updateValue(next);
                cs = (ClientSession) OBEXConnector.open(adrProto);
                sendApp();

            } catch (Exception e) {
                System.out.println(e);
            }
        }
    }

    /**
     * Stuurt de applicatie naar de cliënt
     *
     * @throws java.io.IOException
     */
    public void sendApp() throws IOException {
        File selFile = new File("jarFiles/WIINF.jar");
        hs = cs.connect(cs.createHeaderSet());
        System.out.println("created header set");
        //byte text[] = "Chat Send File Test Message from PC".getBytes("iso-8859-1");
        byte text[] = getBytesFromFile(selFile);
        hs.setHeader(HeaderSet.NAME, selFile.getName());
        hs.setHeader(HeaderSet.TYPE, "text");
        //hs.setHeader(0x49, text); // if everything fits inside a packet, the data can be packed in the PUT command
        System.out.println("putting....");
        Operation po = cs.put(hs);
        System.out.println("put....");
        po.openOutputStream().write(text);
        po.close();
        cs.disconnect(null);
        cs.close();
        System.out.println("closed...");
    }

    /**
     * Stopt de tijd in de hashmap waarop de cliënt is benaderd met de jar-file
     *
     * @param next Het bluetooth adres
     */
    public void updateValue(String next) {
        date = new Date();
        tijd = date.getTime();
        hm.put(next, tijd);

    }

    public static byte[] getBytesFromFile(File file) throws IOException {
        InputStream is = new FileInputStream(file);

        // Get the size of the file
        long length = file.length();

        // You cannot create an array using a long type.
        // It needs to be an int type.
        // Before converting to an int type, check
        // to ensure that file is not larger than Integer.MAX_VALUE.
        if (length > Integer.MAX_VALUE) {
            System.out.println("File is too large\n");
            // File is too large
        }

        // Create the byte array to hold the data
        byte[] bytes = new byte[(int) length];

        // Read in the bytes
        int offset = 0;
        int numRead = 0;
        while (offset < bytes.length && (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) {
            offset += numRead;
        }

        // Ensure all the bytes have been read in
        if (offset < bytes.length) {
            throw new IOException("Could not completely read file " + file.getName());
        }

        // Close the input stream and return bytes
        is.close();
        return bytes;
    }

    public void run() {
        while (true) {
            try {
                new RemoteDeviceDiscovery(this);

            } catch (Exception ex) {
                Logger.getLogger(serverSender.class.getName()).log(Level.SEVERE, null, ex);
            }
            vectorToHashMap();
            maakVerbinding();
        }
    }
}
